package com.blackcat.demo.zip;

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
* 压缩文件
* @author zhanghui
* @since 2023/9/13 10:32
*/
public class ZipExample {

    public static void main(String[] args) {
        zipFile("/Users/blackcat/Downloads/file.zip",  "/Users/blackcat/Downloads/mmi_upload_transcount.sql");
        //zipFolder("folder.zip",  "/Users/blackcat/Downloads/11111");
    }

    /**
     * 压缩文件
     * @param zipFileName 压缩后的压缩包名称
     *                    只输入压缩包名，压缩文件会在jar 包所在路径下。示例：file.zip
     *                    输入路径加名称，压缩文件会在指定路径下。示例：/path/file.zip
     * @param path 需要压缩的文件路径
     */
    public static void zipFile(String zipFileName,String path) {
        FileInputStream fileInputStream;
        FileOutputStream fileOutputStream;
        ZipOutputStream zipOutputStream = null;
        BufferedInputStream bufferInputStream = null;
        try {
            // zipFileName为压缩文件的名称（xx.zip），首先在某个目录下创建一个.zip结尾的文件
            File zipFile = new File(zipFileName);
            fileOutputStream = new FileOutputStream(zipFile);
            zipOutputStream = new ZipOutputStream(new BufferedOutputStream(fileOutputStream));
            // 创建读写缓冲区
            byte[] bufs = new byte[1024 * 10];
            File file = new File(path);
            if (file.exists()) {
                ZipEntry zipEntry;
                // 压缩文件下的目录分级，如果不分目录可以直接用fileName.文件后缀
                zipEntry = new ZipEntry(file.getName()+getFileExtension(file));
                // 创建ZIP实体，并添加进压缩包
                zipOutputStream.putNextEntry(zipEntry);
                // 读取待压缩的文件并写进压缩包里
                fileInputStream = new FileInputStream(file);
                bufferInputStream = new BufferedInputStream(fileInputStream, 1024 * 10);
                int read = 0;
                while ((read = bufferInputStream.read(bufs, 0, 1024 * 10)) != -1) {
                    zipOutputStream.write(bufs, 0, read);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (bufferInputStream != null) {
                    bufferInputStream.close();
                }
                if (zipOutputStream != null) {
                    zipOutputStream.close();
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 压缩文件夹
     * @param zipFileName 压缩后的压缩包名称
     *                    只输入压缩包名，压缩文件会在jar 包所在路径下。示例：file.zip
     *                    输入路径加名称，压缩文件会在指定路径下。示例：/path/file.zip
     * @param folder 需要压缩的文件夹路径
     */
    public static void zipFolder(String zipFileName,String folder) {
        FileInputStream fileInputStream;
        FileOutputStream fileOutputStream;
        ZipOutputStream zipOutputStream = null;
        BufferedInputStream bufferInputStream = null;
        try {
            // zipFileName为压缩文件的名称（xx.zip），首先在某个目录下创建一个.zip结尾的文件
            File zipFile = new File(zipFileName);
            fileOutputStream = new FileOutputStream(zipFile);
            zipOutputStream = new ZipOutputStream(new BufferedOutputStream(fileOutputStream));
            // 创建读写缓冲区
            byte[] bufs = new byte[1024 * 10];
            File directory = new File(folder);
            File[] files = directory.listFiles();
            for (File file : files) {
                if (file.exists()) {
                    ZipEntry zipEntry;
                    // 压缩文件下的目录分级，如果不分目录可以直接用fileName.文件后缀
                    zipEntry = new ZipEntry(file.getName()+getFileExtension(file));
//                    zipEntry = new ZipEntry(file.getAbsolutePath() + getFileExtension(file));
                    // 创建ZIP实体，并添加进压缩包
                    zipOutputStream.putNextEntry(zipEntry);
                    // 读取待压缩的文件并写进压缩包里
                    fileInputStream = new FileInputStream(file);
                    bufferInputStream = new BufferedInputStream(fileInputStream, 1024 * 10);
                    int read = 0;
                    while ((read = bufferInputStream.read(bufs, 0, 1024 * 10)) != -1) {
                        zipOutputStream.write(bufs, 0, read);
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (bufferInputStream != null) {
                    bufferInputStream.close();
                }
                if (zipOutputStream != null) {
                    zipOutputStream.close();
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 获取文件后缀名
     * @param file 文件
     */
    private static String getFileExtension(File file) {
        String fileName = file.getName();
        if (fileName.lastIndexOf(".") != -1 && fileName.lastIndexOf(".") != 0)
            return fileName.substring(fileName.lastIndexOf(".") + 1);
        else return " ";
    }


    private static void addToZipFile(String fileName, String fileAbsolutePath, ZipOutputStream zipOutputStream) throws IOException {
        // 创建ZipEntry对象并设置文件名
        ZipEntry entry = new ZipEntry(fileName);
        zipOutputStream.putNextEntry(entry);

        // 读取文件内容并写入Zip文件
        try (FileInputStream fileInputStream = new FileInputStream(fileAbsolutePath)) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = fileInputStream.read(buffer)) != -1) {
                zipOutputStream.write(buffer, 0, bytesRead);
            }
        }

        // 完成当前文件的压缩
        zipOutputStream.closeEntry();
    }
}
